package org.pidan.basic.multiThread;

/**
 * {@code @description}: Synchronized 锁
 * <p>
 * 在某些情况下，我们编写的方法体可能比较大，同时存在一些比较耗时的操作，而需要同步的代码又只有一小部分，
 * 如果直接对整个方法进行同步操作，可能会得不偿失，此时我们可以使用同步代码块的方式对需要同步的代码进行包裹，这样就无需对整个方法进行同步操作了
 * <p>
 * 本例为 同步代码块
 * <p>
 * {@code @author}: huangyuxin
 * {@code @date}: 2023-12-13
 */
public class SynchronizedDaiMaKuai implements Runnable {

    public static SynchronizedDaiMaKuai daiMaKuai = new SynchronizedDaiMaKuai();

    public static int num = 0;


    // 将synchronized作用于一个给定的实例对象instance，即当前实例对象就是锁对象，
    // 每次当线程进入synchronized包裹的代码块时就会要求当前线程持有instance实例对象锁，
    // 如果当前有其他线程正持有该对象锁，那么新到的线程就必须等待，这样也就保证了每次只有一个线程执行i++;操作
    @Override
    public void run() {
        //其他耗时逻辑
        //...

        synchronized (daiMaKuai) {
            for (int i = 0; i < 1000; i++) {
                num++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(daiMaKuai);
        Thread t2 = new Thread(daiMaKuai);
        Thread t3 = new Thread(daiMaKuai);

        t1.start();
        t2.start();
        t3.start();

        // 等待三个线程结束
        t1.join();
        t2.join();
        t3.join();

        //输出结果
        System.out.println(SynchronizedDaiMaKuai.num);
    }

}
